package com.laundry.user.data.repository

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import com.laundry.user.data.api.*
import com.laundry.user.data.database.LaundryDatabase
import com.laundry.user.data.model.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull

/**
 * 用户数据仓库
 */
class UserRepository(private val context: Context) {
    
    private val database = LaundryDatabase.getDatabase(context)
    private val apiService = NetworkModule.getApiService()
    private val tokenManager = NetworkModule.getTokenManager()
    
    // ==================== 认证相关 ====================
    
    /**
     * 发送验证码
     */
    suspend fun sendVerificationCode(phone: String): Result<String> {
        return try {
            val request = SendCodeRequest(phone)
            val response = apiService.sendVerificationCode(request)
            
            if (response.isSuccessful && response.body()?.success == true) {
                Result.success(response.body()?.data ?: "验证码已发送")
            } else {
                Result.failure(Exception(response.body()?.message ?: "发送失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 验证码登录
     */
    suspend fun login(phone: String, code: String): Result<User> {
        return try {
            val request = LoginRequest(
                phone = phone,
                code = code,
                deviceId = getDeviceId(),
                appVersion = com.laundry.user.BuildConfig.VERSION_NAME
            )
            val response = apiService.login(request)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val loginResponse = response.body()?.data
                if (loginResponse != null) {
                    // 保存Token
                    tokenManager.saveTokens(
                        loginResponse.accessToken,
                        loginResponse.refreshToken,
                        loginResponse.expiresIn
                    )
                    
                    // 保存用户信息到本地数据库
                    val user = loginResponse.user
                    if (user != null) {
                        database.userDao().insertUser(user)
                        Result.success(user)
                    } else {
                        Result.failure(Exception("用户信息为空"))
                    }
                } else {
                    Result.failure(Exception("登录响应为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "登录失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 退出登录
     */
    suspend fun logout() {
        try {
            // 清除Token
            tokenManager.clearTokens()
            
            // 清除本地数据
            database.userDao().deleteAllUsers()
            // TODO: 添加其他数据清除方法
            // database.orderDao().deleteAllOrders()
            // database.chatDao().deleteAllChatSessions()
            // database.notificationDao().deleteAllNotifications()
            // ... 清除其他敏感数据
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    /**
     * 检查登录状态
     */
    fun isLoggedIn(): Boolean {
        return tokenManager.isLoggedIn()
    }
    
    // ==================== 用户信息相关 ====================
    
    /**
     * 获取当前用户信息
     */
    suspend fun getCurrentUser(): User? {
        return try {
            // 先从本地数据库获取
            val localUser = database.userDao().getUserById(getCurrentUserId())
            if (localUser != null) {
                return localUser
            }
            
            // 本地没有则从服务器获取
            val response = apiService.getUserProfile()
            if (response.isSuccessful && response.body()?.success == true) {
                val user = response.body()?.data
                if (user != null) {
                    database.userDao().insertUser(user)
                    user
                } else {
                    null
                }
            } else {
                null
            }
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
    
    /**
     * 更新用户信息
     */
    suspend fun updateUserProfile(user: User): Result<User> {
        return try {
            val response = apiService.updateUserProfile(user)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val updatedUser = response.body()?.data
                if (updatedUser != null) {
                    database.userDao().updateUser(updatedUser)
                    Result.success(updatedUser)
                } else {
                    Result.failure(Exception("更新后的用户信息为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "更新失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 上传头像
     */
    suspend fun uploadAvatar(imagePath: String): Result<String> {
        return try {
            val file = java.io.File(imagePath)
            val requestFile = okhttp3.RequestBody.create(
                "image/*".toMediaTypeOrNull(),
                file
            )
            val body = okhttp3.MultipartBody.Part.createFormData("avatar", file.name, requestFile)
            
            val response = apiService.uploadAvatar(body)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val avatarUrl = response.body()?.data
                if (!avatarUrl.isNullOrEmpty()) {
                    Result.success(avatarUrl)
                } else {
                    Result.failure(Exception("头像URL为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "上传失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    // ==================== 地址管理 ====================
    
    /**
     * 获取地址列表
     */
    fun getAddresses(): Flow<List<Address>> = flow {
        try {
            // 先发射本地数据
            database.addressDao().getAddresses(getCurrentUserId()).collect { localAddresses ->
                emit(localAddresses)
            }
            
            // 然后从服务器同步
            val response = apiService.getAddresses()
            if (response.isSuccessful && response.body()?.success == true) {
                val addresses = response.body()?.data ?: emptyList()
                // 更新本地数据库
                addresses.forEach { address ->
                    database.addressDao().insertAddress(address)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    
    /**
     * 添加地址
     */
    suspend fun addAddress(address: Address): Result<Address> {
        return try {
            val response = apiService.addAddress(address)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val newAddress = response.body()?.data
                if (newAddress != null) {
                    database.addressDao().insertAddress(newAddress)
                    Result.success(newAddress)
                } else {
                    Result.failure(Exception("新地址信息为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "添加失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 更新地址
     */
    suspend fun updateAddress(address: Address): Result<Address> {
        return try {
            val response = apiService.updateAddress(address.id, address)
            
            if (response.isSuccessful && response.body()?.success == true) {
                val updatedAddress = response.body()?.data
                if (updatedAddress != null) {
                    database.addressDao().updateAddress(updatedAddress)
                    Result.success(updatedAddress)
                } else {
                    Result.failure(Exception("更新后的地址信息为空"))
                }
            } else {
                Result.failure(Exception(response.body()?.message ?: "更新失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 删除地址
     */
    suspend fun deleteAddress(addressId: String): Result<String> {
        return try {
            val response = apiService.deleteAddress(addressId)
            
            if (response.isSuccessful && response.body()?.success == true) {
                // 从本地数据库删除
                val address = database.addressDao().getAddressById(addressId)
                if (address != null) {
                    database.addressDao().deleteAddress(address)
                }
                Result.success("删除成功")
            } else {
                Result.failure(Exception(response.body()?.message ?: "删除失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 设置默认地址
     */
    suspend fun setDefaultAddress(addressId: String): Result<String> {
        return try {
            val response = apiService.setDefaultAddress(addressId)
            
            if (response.isSuccessful && response.body()?.success == true) {
                // 更新本地数据库
                database.addressDao().clearDefaultAddress(getCurrentUserId())
                database.addressDao().setDefaultAddress(addressId)
                Result.success("设置成功")
            } else {
                Result.failure(Exception(response.body()?.message ?: "设置失败"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    // ==================== 工具方法 ====================
    
    /**
     * 获取当前用户ID
     */
    private fun getCurrentUserId(): String {
        // 这里应该从Token中解析用户ID，或者从本地存储获取
        // 简化实现，实际项目中需要更安全的方式
        return context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE)
            .getString("current_user_id", "") ?: ""
    }
    
    /**
     * 获取设备ID
     */
    private fun getDeviceId(): String {
        return android.provider.Settings.Secure.getString(
            context.contentResolver,
            android.provider.Settings.Secure.ANDROID_ID
        ) ?: ""
    }
}
